#include "centroid.h"

#include <math.h>

// distanta intre doi descriptori fourier
unsigned int operator-(const FourierSerie &lhs, const FourierSerie &rhs)
{
	FourierSerie::const_iterator itl = lhs.begin(), itr = rhs.begin();
	double result = 0.0;

	while (itl != lhs.end() && itr != rhs.end())
	{
		const Complex &c1 = (*itl).first;
		const Complex &c2 = (*itr).first;

		result += (c1.first - c2.first) * (c1.first - c2.first) + 
					(c1.second - c2.second) * (c1.second - c2.second);

		itl++;
		itr++;
	}

	return (unsigned int)(sqrt(result) + 0.5);
}

Centroid::Centroid() : size(0)
{
}

Centroid::~Centroid()
{
}

// distanta de la un centroid la un fourier descriptor
unsigned int Centroid::operator-(const FourierSerie &serie)
{
	return this->serie - serie;
}


// adaugarea unui fourier descriptor la un centroid
Centroid& Centroid::operator<<(const FourierSerie &rhs)
{
	if (!size)
	{
		size = 1;
		serie = rhs;
		return *this;
	}

	FourierSerie::iterator it_serie = serie.begin();
	FourierSerie::const_iterator itr = rhs.begin();

	while (it_serie != serie.end() && itr != rhs.end())
	{
		Complex &c1 = (*it_serie).first;
		const Complex &c2 = (*itr).first;

		c1.first  = (size * c1.first  + c2.first)  / (size + 1);
		c1.second = (size * c1.second + c2.second) / (size + 1);

		it_serie++;
		itr++;
	}

	size++;

	return *this;
}

// cautam un centroid dupa nume
bool centroid_search(CentroidList &centroid_list, const wchar_t *label, Centroid **centroid)
{
	for (CentroidList::iterator it = centroid_list.begin(); 
									it != centroid_list.end(); it++)
	{
		if ( (*it).label == label )
		{
			*centroid = &*it;
			return true;
		}
	}

	return false;
}

// cautam centroidul cel mai apropiat si returnam si distanta pana la el
// se returneaza max int daca nu se gaseste
unsigned int centroid_search(CentroidList &centroid_list, const FourierSerie &serie, Centroid **centroid)
{
	unsigned int min = 0xFFFFFFFF, dist;

	for (CentroidList::iterator it = centroid_list.begin(); 
									it != centroid_list.end(); it++)
	{

		if ( (dist = *it - serie) < min )
		{
			min = dist;
			*centroid = &*it;
		}
	}

	return min;

}